from apscheduler.schedulers.background import BackgroundScheduler
from app.utils.logger_util import LoggerUtil

class SchedulerUtil:
    _instance = None
    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = cls()
            cls._instance.logger.info(f"SchedulerUtil调度器初始化成功 实例ID:{id(cls._instance)}")
        return cls._instance

    def __init__(self):
        """
        初始化定时任务调度器
        """
        self.scheduler = BackgroundScheduler()
        self.scheduler.start()
        self.logger = LoggerUtil.get_logger()

    def add_job(self, func, trigger, **kwargs):
        """
        添加定时任务到调度器中

        :param func: 要执行的任务函数
        :param trigger: 触发方式，如 'interval'（间隔触发）、'cron'（定时表达式触发）等
        :param kwargs: 其他参数，根据不同触发方式传递相应参数，例如：
                       - 对于 'interval' 触发，可传递参数如seconds，hours，days，minutes（间隔分钟数）等；例如：scheduler.add_job(func, 'interval', seconds = 10)会使func函数每隔 10 秒执行一次
                       - 对于 'cron' 触发，可传递参数如 'year'、'month'、'day'、'hour'、'minute' 等定时任务表达式相关参数.例如，scheduler.add_job(func, 'cron', minute = '0', hour = '12')表示func函数每天中午 12 点整执行。
                       start_date参数来指定定时任务的起始时间。这个参数接受一个datetime类型的对象或者一个可以被解析为日期时间格式的字符串（例如'2024 - 12 - 31 12:00:00'）。
                       end_date参数，用于指定定时任务的结束时间。同样，它接受一个datetime类型的对象或者日期时间格式的字符串。
        """
        try:
            job = self.scheduler.add_job(func, trigger, **kwargs)
            job_id = job.id
            self.logger.info(f"成功添加定时任务，函数：{func.__name__}，触发方式：{trigger}，参数：{kwargs}，任务ID：{job_id}")
            return job_id
        except Exception as e:
            self.logger.error(f"添加定时任务失败，函数：{func.__name__}，错误信息：{e}")
            return None

    def remove_job(self, job_id):
        """
        从调度器中移除指定 ID 的定时任务

        :param job_id: 要移除的定时任务的唯一标识符
        """
        try:
            self.scheduler.remove_job(job_id)
            self.logger.info(f"成功移除定时任务，任务 ID：{job_id}")
        except Exception as e:
            self.logger.error(f"移除定时任务失败，任务 ID：{job_id}，错误信息：{e}")

    def pause_job(self, job_id):
        """
        暂停指定 ID 的定时任务

        :param job_id: 要暂停的定时任务的唯一标识符
        """
        try:
            self.scheduler.pause_job(job_id)
            self.logger.info(f"成功暂停定时任务，任务 ID：{job_id}")
        except Exception as e:
            self.logger.error(f"暂停定时任务失败，任务 ID：{job_id}，错误信息：{e}")

    def resume_job(self, job_id):
        """
        恢复指定 ID 的定时任务（如果之前被暂停）

        :param job_id: 要恢复的定时任务的唯一标识符
        """
        try:
            self.scheduler.resume_job(job_id)
            self.logger.info(f"成功恢复定时任务，任务 ID：{job_id}")
        except Exception as e:
            self.logger.error(f"恢复定时任务失败，任务 ID：{job_id}，错误信息：{e}")

    def shutdown(self):
        """
        关闭定时任务调度器，结束所有定时任务
        """
        try:
            self.scheduler.shutdown()
            self.logger.info("定时任务调度器已关闭")
        except Exception as e:
            self.logger.error(f"关闭定时任务调度器失败，错误信息：{e}")